package util.methods;

import assem.DBConn;
import assem.Schema;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import javax.swing.JOptionPane;

import util.Debug.ErrorReport;

public class Version {
	public static final String strRelDate = "(7July15)"; 
	public static final String strPAVEver = "1.3.3";
	// also set in sTCW schema.java, used in mTCW globals (but doesn't effect anything)
	public static final String strDBver = "4.1";  
	public static final String URL = "http://www.agcol.arizona.edu ";
	public static double dDBver = -1.0; 
	public static String sDBver = "";
	private static final int REQUIRED_JAVA_MAJOR_VERSION = 1; 
	private static final int REQUIRED_JAVA_MINOR_VERSION = 6; 
	
	// also saved in assembly object as string format
	public static double getDBversion () {
		return dDBver;
	}
	public static float fltSchema (Connection dbConnection) 
	{
		Statement stmt;
		float v = 1;
		
		try {
			if (!doesTableExist(dbConnection, "schemver")) return v;
			stmt = dbConnection.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT schemver FROM schemver");
			if ( rs.next() ) {
				sDBver = rs.getString("schemver.schemver");
				v = Float.valueOf(sDBver.trim()).floatValue();
				dDBver = v;
			}
		} catch (SQLException e) {
			return v;
		} 
		return v;
	}
	
	static public void updateSchema(String host, String db, String user, String passwd)  
	{
		DBConn dbconn = null;
		try {
			dbconn = new DBConn(host, db,user, passwd);
			Schema s = new Schema(dbconn);
			if (!s.current())
			{
				s.update();
			}
		}
		catch (Exception e) {
			ErrorReport.reportError(e, "Unable to update schema");
		}
	}
	public static boolean doesFieldExist(Connection dbConn, String table, String field)
	{
		Statement stmt;
		try {
			stmt = dbConn.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT * FROM " + table + " LIMIT 1"); 
			ResultSetMetaData rsmd = rs.getMetaData(); 
			int numColumns = rsmd.getColumnCount(); 
			for (int i=1; i<numColumns+1; i++) 
			{ 
				String columnName = rsmd.getColumnName(i); 
				if(columnName.equalsIgnoreCase(field))
					return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} 
		return false;
	}	
	
	public static boolean doesTableExist(Connection dbConn, String table)
	{
		Statement stmt;
		try {
			stmt = dbConn.createStatement();
			ResultSet rs = stmt.executeQuery("SHOW TABLES");
			while(rs.next()) {
				if(table.equals(rs.getString(1)))
					return true;
			}
			return false;
		} catch (SQLException e) { // fails if the table doesn't exist
			return false;
		} 
	}
	
	public static boolean checkJavaSupported() {	
		String version = System.getProperty("java.version");
		if (version != null) {
			String[] subs = version.split("\\.");
			int major = 0;
			int minor = 0;

			if (subs.length > 0) major  = Integer.valueOf(subs[0]);
			if (subs.length > 1) minor  = Integer.valueOf(subs[1]);
			
			if (major < REQUIRED_JAVA_MAJOR_VERSION
				|| (major >= REQUIRED_JAVA_MAJOR_VERSION && minor < REQUIRED_JAVA_MINOR_VERSION))
			{
				String msg = 
						"The installed Java version is "
					    + getInstalledJavaVersionStr() + ".  \n"
					    + "TCW requires version "
					    + getRequiredJavaVersionStr() + " or later.  \n"
					    + "Please visit http://java.com/download/ to upgrade.";
				System.err.println(msg);
				JOptionPane.showMessageDialog(null,msg);
				return false;
			}
			else
				return true;
		}
		else 
			System.err.println("Could not determine java version.");
		
		return false;
	}
	
	private static String getRequiredJavaVersionStr() {
		return REQUIRED_JAVA_MAJOR_VERSION
				+ "." + REQUIRED_JAVA_MINOR_VERSION;
	}

	private static String getInstalledJavaVersionStr() {
		return System.getProperty("java.version");
	}
	
	/** Sanity check the innodb buffer pool size. 
	// It should be at least 100M for a reasonable sized assembly - but they would
	// probably want it higher, and also there are several other settings they
	// need to look at. Hence, the error msg needs to point them to the
	// documentation, and we may want to adjust the 100M number.
	// TODO: finish documentation, finalize number.
	 ***/
	public static boolean checkInnodbBufPool(Connection conn) throws Exception
	{
		Statement st = conn.createStatement();
		ResultSet rs = st.executeQuery("show variables like 'innodb_buffer_pool_size'");
		if (rs.first())
		{
			long size = rs.getLong(2);
			
			if (size < 100000000L)
			{
				return false;
			}
		}
		return true;
	}
	public static long memUseMB()
	{
		//System.gc();  // it's more accurate after a gc of course but this is slow
		long total = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
		return total/1000000;

	}	
	public static void printPAVEVersion()
	{
		System.err.println("\nTCW (Transcriptome Computational Workbench) v" + strPAVEver + "\n");
	}
	public static boolean needsRPKMUpgrade(Connection c) throws Exception
	{
		Statement s = c.createStatement();
		if (doesTableExist(c,"assembly"))
		{
			if (doesFieldExist(c,"assembly","ppx"))
			{
				ResultSet rs = s.executeQuery("select ppx from assembly");
				if (rs.first())
				{
					return (0 != rs.getInt("ppx"));
				}
			}
		}

		return false;
	}
	

}
